import * as THREE from 'three';

// 引入轨道控制器扩展库OrbitControls.js
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';

/**
 * 创建3D场景
 */
// 创建3D场景对象Scene
const scene = new THREE.Scene();

//创建一个长方体几何对象Geometry
const geometry = new THREE.BoxGeometry(100, 60, 20);

//创建一个材质对象Material MeshLambertMaterial（兰伯特网格材质）受光照影响
const material = new THREE.MeshLambertMaterial();

// 两个参数分别为几何体geometry、材质material
const mesh = new THREE.Mesh(geometry, material); //网格模型对象Mesh

//点光源：两个参数分别表示光源颜色和光照强度
// 参数1：0xffffff是纯白光,表示光源颜色
// 参数2：1.0,表示光照强度，可以根据需要调整
const pointLight = new THREE.PointLight(0xffffff, 1.0);

pointLight.intensity = 1.0; //光照强度
pointLight.decay = 0.0; //设置光源不随距离衰减
//设置网格模型在三维空间中的位置坐标，默认是坐标原点
mesh.position.set(0, 0, 0);

scene.add(mesh);

// 你可以对比不同光照强度明暗差异(传播同样距离)

//点光源位置
pointLight.position.set(400, 0, 0); //点光源放在x轴上
pointLight.position.set(200, 200, 100);

scene.add(pointLight); //点光源添加到场景中

// // 光源辅助观察
const pointLightHelper = new THREE.PointLightHelper(pointLight, 10);
scene.add(pointLightHelper);

pointLight.position.set(100, 60, 50);

//环境光:没有特定方向，整体改变场景的光照明暗
// const ambient = new THREE.AmbientLight(0xffffff, 0.4);
// scene.add(ambient);

// 平行光
const directionalLight = new THREE.DirectionalLight(0xffffff, 1.5);
// 设置光源的方向：通过光源position属性和目标指向对象的position属性计算
directionalLight.position.set(80, 100, 50);
// 方向光指向对象网格模型mesh，可以不设置，默认的位置是0,0,0
directionalLight.target = mesh;
// directionalLight.position.set(100, 0, 0);
directionalLight.position.set(0, 100, 0);
// directionalLight.position.set(100, 100, 100);
// directionalLight.position.set(100, 60, 50);

scene.add(directionalLight);

// DirectionalLightHelper：可视化平行光
const dirLightHelper = new THREE.DirectionalLightHelper(
  directionalLight,
  5,
  0xff0000
);
scene.add(dirLightHelper);

/**
 * 透视投影相机
 */

// width和height用来设置Three.js输出的Canvas画布尺寸(像素px)
const width = 1300; //宽度
const height = 800; //高度
// 30:视场角度, width / height:Canvas画布宽高比, 1:近裁截面, 3000：远裁截面
const camera = new THREE.PerspectiveCamera(30, width / height, 1, 3000);

//相机在Three.js三维坐标系中的位置
// 根据需要设置相机位置具体值
camera.position.set(200, 200, 200);
// camera.position.set(-100, 0, 0);

//相机观察目标指向Threejs 3D空间中某个位置
camera.lookAt(0, 0, 0); //坐标原点

/**
 * 三维坐标系-加强三维空间认识
 */
// AxesHelper：辅助观察的坐标系
const axesHelper = new THREE.AxesHelper(150);
scene.add(axesHelper);

/**
 * 渲染器
 */

// 创建渲染器对象
const renderer = new THREE.WebGLRenderer();
renderer.setSize(width, height); //设置three.js渲染区域的尺寸(像素px)

renderer.render(scene, camera); //执行渲染操作

document.getElementById('webgl').appendChild(renderer.domElement);

// 设置相机控件轨道控制器OrbitControls
const controls = new OrbitControls(camera, renderer.domElement);
// 如果OrbitControls改变了相机参数，重新调用渲染器渲染三维场景
controls.addEventListener('change', function () {
  renderer.render(scene, camera); //执行渲染操作
}); //监听鼠标、键盘事件

/**
 * OrbitControls本质上就是改变相机的参数，比如相机的位置属性，
 * 改变相机位置也可以改变相机拍照场景中模型的角度，实现模型的360度旋转预览效果，
 * 改变透视投影相机距离模型的距离，就可以改变相机能看到的视野范围。
 */
controls.addEventListener('change', function () {
  // 浏览器控制台查看相机位置变化
  console.log('camera.position', camera.position);
});
